"""
distance_calculator.py

负责"距离测量模式"的开启与关闭，通过鼠标点击事件获取用户在图像上的两个点击位置。
计算两点之间的实际地理距离和像素距离，并计算当前的比例尺。
"""

from PyQt5.QtWidgets import (
    QDialog, QVBoxLayout, QHBoxLayout, QLabel, 
    QPushButton, QMessageBox
)
from PyQt5.QtCore import Qt
import matplotlib.patches as patches
import matplotlib.lines as mlines
from orthophoto_utils import (
    transform_coordinate,
    calculate_distance,
    calculate_pixel_distance,
    calculate_scale
)

class DistanceResultDialog(QDialog):
    """
    显示距离测量结果的对话框
    """
    def __init__(self, parent=None, pixel_distance=0, real_distance=0, scale=""):
        super().__init__(parent)
        self.setWindowTitle("距离测量结果")
        self.setMinimumWidth(300)
        
        layout = QVBoxLayout()
        
        # 像素距离
        pixel_layout = QHBoxLayout()
        pixel_layout.addWidget(QLabel("像素距离:"))
        pixel_layout.addWidget(QLabel(f"{pixel_distance:.2f} 像素"))
        layout.addLayout(pixel_layout)
        
        # 实际距离
        real_layout = QHBoxLayout()
        real_layout.addWidget(QLabel("实际距离:"))
        real_layout.addWidget(QLabel(f"{real_distance:.2f} 米"))
        layout.addLayout(real_layout)
        
        # 比例尺
        scale_layout = QHBoxLayout()
        scale_layout.addWidget(QLabel("比例尺:"))
        scale_layout.addWidget(QLabel(scale))
        layout.addLayout(scale_layout)
        
        # 确定按钮
        btn_ok = QPushButton("确定")
        btn_ok.clicked.connect(self.accept)
        layout.addWidget(btn_ok)
        
        self.setLayout(layout)


class DistanceCalculator:
    def __init__(self, canvas, parent=None):
        self.canvas = canvas
        self.parent = parent
        self.is_measuring = False
        self.points = []  # 存储点击的点 [(col1, row1), (col2, row2)]
        self.cid = None  # mpl_connect 的连接ID
        
        # 用于显示测量线
        self.line = None
        self.markers = []
        
    def toggle_distance_measure(self):
        """
        切换距离测量模式
        """
        if self.is_measuring:
            # 退出距离测量模式
            self.is_measuring = False
            if self.cid is not None:
                self.canvas.mpl_disconnect(self.cid)
                self.cid = None
            self.clear_measurement()
        else:
            # 进入距离测量模式
            self.is_measuring = True
            self.points = []
            self.cid = self.canvas.mpl_connect('button_press_event', self.on_click)
            QMessageBox.information(self.parent, "距离测量", "请点击第一个点")
    
    def on_click(self, event):
        """
        处理鼠标点击事件
        """
        if event.button != 1:  # 1 表示鼠标左键
            return
        if not self.canvas or event.inaxes != self.canvas.ax:
            return
            
        col, row = event.xdata, event.ydata
        
        if len(self.points) == 0:
            # 第一个点
            self.points.append((col, row))
            
            # 添加标记
            marker = self.canvas.ax.plot(col, row, 'ro', markersize=5)[0]
            self.markers.append(marker)
            self.canvas.draw()
            
            QMessageBox.information(self.parent, "距离测量", "请点击第二个点")
        elif len(self.points) == 1:
            # 第二个点
            self.points.append((col, row))
            
            # 添加标记和连线
            marker = self.canvas.ax.plot(col, row, 'ro', markersize=5)[0]
            self.markers.append(marker)
            
            col1, row1 = self.points[0]
            self.line = self.canvas.ax.plot([col1, col], [row1, row], 'r-', linewidth=2)[0]
            
            self.canvas.draw()
            
            # 计算距离和比例尺
            self.calculate_and_show_result()
            
            # 重置点击状态，允许再次测量
            self.points = []
    
    def calculate_and_show_result(self):
        """
        计算两点之间的距离和比例尺，并显示结果
        """
        if len(self.points) != 2:
            return
            
        col1, row1 = self.points[0]
        col2, row2 = self.points[1]
        
        # 计算像素距离
        pixel_distance = calculate_pixel_distance(col1, row1, col2, row2)
        
        # 如果有地理坐标变换信息，计算实际距离
        if self.canvas.transform is not None:
            try:
                # 将像素坐标转换为地理坐标
                lon1, lat1 = transform_coordinate(col1, row1, self.canvas.transform)
                lon2, lat2 = transform_coordinate(col2, row2, self.canvas.transform)
                
                # 计算实际距离（米）
                real_distance = calculate_distance(lon1, lat1, lon2, lat2)
                
                # 计算比例尺
                scale = calculate_scale(pixel_distance, real_distance)
                
                # 显示结果对话框
                dialog = DistanceResultDialog(
                    self.parent,
                    pixel_distance=pixel_distance,
                    real_distance=real_distance,
                    scale=scale
                )
                
                # 显示对话框并在对话框关闭后清除测量线
                result = dialog.exec_()
                # 无论用户点击确定还是关闭对话框，都清除测量线
                self.clear_measurement()
                
            except Exception as e:
                QMessageBox.warning(self.parent, "计算错误", f"计算距离时出错: {str(e)}")
                # 发生错误时也清除测量线
                self.clear_measurement()
        else:
            QMessageBox.warning(self.parent, "无地理信息", "当前图像没有地理坐标信息，无法计算实际距离")
            # 无地理信息时也清除测量线
            self.clear_measurement()
    
    def clear_measurement(self):
        """
        清除测量线和标记
        """
        if self.line:
            self.line.remove()
            self.line = None
            
        for marker in self.markers:
            marker.remove()
        self.markers = []
        
        if self.canvas:
            self.canvas.draw()
    
    def is_in_measure_mode(self):
        """
        返回是否处于测量模式
        """
        return self.is_measuring 